package com.ytjj.qmyx.supplychain.service;

import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ytjj.qmyx.supplychain.common.api.CommonResult;
import com.ytjj.qmyx.supplychain.common.constants.BankerConstants;
import com.ytjj.qmyx.supplychain.common.constants.OrderTimerConstants;
import com.ytjj.qmyx.supplychain.common.enums.OrderStatusEnums;
import com.ytjj.qmyx.supplychain.common.exception.ApiException;
import com.ytjj.qmyx.supplychain.common.model.request.ExpressRecordsRequest;
import com.ytjj.qmyx.supplychain.common.model.request.OrderExpressModifiedRequest;
import com.ytjj.qmyx.supplychain.common.model.request.OrderQueryRequest;
import com.ytjj.qmyx.supplychain.common.model.response.NewBankerOrderResponse;
import com.ytjj.qmyx.supplychain.common.model.response.OrderQueryResponse;
import com.ytjj.qmyx.supplychain.common.utils.CopyWriterConfigUtil;
import com.ytjj.qmyx.supplychain.common.utils.DingDingWebHookUtil;
import com.ytjj.qmyx.supplychain.common.utils.ExpressDicUtil;
import com.ytjj.qmyx.supplychain.common.utils.HttpClientUtil;
import com.ytjj.qmyx.supplychain.common.utils.feishu.FeiShuUtil;
import com.ytjj.qmyx.supplychain.mapper.*;
import com.ytjj.qmyx.supplychain.mapper.entity.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RefreshScope
public class BankerOrderService {
    @Resource
    private BankerExportRecordMapper bankerExportRecordMapper;
    @Resource
    private BankerOrderMapper bankerOrderMapper;
    @Resource
    private ExpressDicService expressDicService;
    @Autowired
    private OrderService orderService;
    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private NotifyUrlInfoMapper notifyUrlInfoMapper;
    @Value(value = "${orderPath:}")
    private String path;
    @Value("${orderServicePath:}")
    private String orderServicePath;
    @Autowired
    private BankerService bankerService;
    @Resource
    private OrderExceptionMapper orderExceptionMapper;
    @Resource
    private ExpressRecordsMapper expressRecordsMapper;
    @Resource
    private OrderExceptionNoteMapper orderExceptionNoteMapper;

    /**
     * 消息模板
     */
    private static final String template = "<<<%s>>> \n 【服务名】: %s(%s) \n 【状态】: %s(%s) \n 【服务ip】: %s \n 【详情】: %s";
    //业务异常发送钉钉机器人消息token
    //关键字：订单
    private static final String business_accessToken = "49ca196e751216fea7a1704e3464cda242e5f46adac35aee3d6507a3ae790149";

    public YxBankerOrder selectByChildOrderNo(String childOrderNo) {
        Example example = new Example(YxBankerOrder.class);
        example.createCriteria().andEqualTo("childOrderNo", childOrderNo);
        List<YxBankerOrder> bankerOrderList = bankerOrderMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(bankerOrderList)) {
            return null;
        }
        return bankerOrderList.get(0);
    }

    public int checkOrdersExpressInfo(List<String> orderNoList) {
        return bankerOrderMapper.checkOrdersExpressInfo(orderNoList);
    }


//    @Transactional(rollbackFor = Exception.class)
    public void fillEmptyExpress(OrderExpressModifiedRequest orderExpressModifiedRequest) {
        //供应商系统登录用户
        YxBanker userInfo = null;
        //供应商链系统登录用户
        String adminName = "";
        try {
            //如果是供应商系统进入获取当前用户
            userInfo = bankerService.getUserInfo();
        } catch (Exception e) {
            //如果是销售渠道系统进入，则设置用户名
            adminName = orderExpressModifiedRequest.getOperator();
        }
        YxBankerOrder yxBankerOrder = new YxBankerOrder();
        if (null != orderExpressModifiedRequest.getId()){
             yxBankerOrder = bankerOrderMapper.selectByPrimaryKey(orderExpressModifiedRequest.getId());
        }else {
            yxBankerOrder.setChildOrderNo(orderExpressModifiedRequest.getChildOrderNo());
            yxBankerOrder= bankerOrderMapper.selectOne(yxBankerOrder);
        }
        //供应链进入
        if (null != orderExpressModifiedRequest.getEnterType() && orderExpressModifiedRequest.getEnterType().equals(1)) {
            YxOrders orders = ordersMapper.selectByPrimaryKey(orderExpressModifiedRequest.getId());
            if (null == orders) {
                log.info("===供应链修改订单物流信息异常,orderId==={}", orderExpressModifiedRequest.getId());
                throw new ApiException("参数错误");
            }
            yxBankerOrder = selectByChildOrderNo(orders.getChildOrderNo());
            if (null == yxBankerOrder) {
                log.info("===供应链修改订单物流信息异常,childOrderNo==={}", orderExpressModifiedRequest.getChildOrderNo());
                throw new ApiException("参数错误");
            }
        }

        YxOrders orders = orderService.queryByChildOrderNoAndShopId(yxBankerOrder.getChildOrderNo(), orderExpressModifiedRequest.getShopId());
        Optional.ofNullable(orders).orElseThrow(() -> new ApiException("订单不存在！"));

        if (Integer.parseInt(OrderStatusEnums.WAIT_DELIVERY.getStatus()) != orders.getOrderStatus()
                && Integer.parseInt(OrderStatusEnums.DELIVERY.getStatus()) != orders.getOrderStatus()) {
            throw new ApiException("订单状态异常，不能继续修改物流信息！");
        }

        log.info("===orderInfoStatus==={}", orders.getOrderStatus());
        if (null != orders && (orders.getOrderStatus().equals(Integer.parseInt(OrderStatusEnums.NO_VALID.getStatus()))
                || orders.getOrderStatus().equals(Integer.parseInt(OrderStatusEnums.REFUND.getStatus())))) {
            throw new ApiException("订单已退货，不能继续导入物流信息!");
        }
        if(org.apache.commons.lang3.StringUtils.isBlank(orderExpressModifiedRequest.getExpressNo())
                || org.apache.commons.lang3.StringUtils.isBlank(orderExpressModifiedRequest.getExpressCompany())){
            throw new ApiException("快递信息不全!");
        }
        Integer updateOrderFlag = 1;
        if (!(orderExpressModifiedRequest.getExpressCompany() + orderExpressModifiedRequest.getExpressNo()).equals(yxBankerOrder.getExpressCode() + yxBankerOrder.getExpressNo())) {
//            String messageText = String
//                    .format(template, "供应商修改了订单快递单号","banker-admin", "update order express","500", "订单快递单号变更","",
//                            JSONObject.toJSONString("供应商修改了订单快递单号，子订单号：" + yxBankerOrder.getChildOrderNo()));
//            FeiShuUtil.sendMsg(messageText);
            orderService.syncOrderExpress(yxBankerOrder.getChildOrderNo(),ExpressDicUtil.getValue(orderExpressModifiedRequest.getExpressCompany().trim()),
                    orderExpressModifiedRequest.getExpressNo().trim(),updateOrderFlag,orders.getShopId(),new Date(),orderExpressModifiedRequest.getExpressCompany().trim());
        }
//        if (!StringUtils.isEmpty(yxBankerOrder.getExpressNo())
//                && !StringUtils.isEmpty(orderExpressModifiedRequest.getExpressNo())
//                && !yxBankerOrder.getExpressNo().equals(orderExpressModifiedRequest.getExpressNo())) {
//            String messageText = String
//                    .format(template, "供应商修改了订单快递单号","banker-admin", "update order express","500", "订单快递单号变更","",
//                            JSONObject.toJSONString("供应商修改了订单快递单号，子订单号：" + yxBankerOrder.getChildOrderNo()));
//            FeiShuUtil.sendMsg(messageText);
//            orderService.syncOrderExpress(yxBankerOrder.getChildOrderNo(),orderExpressModifiedRequest.getExpressCompany().trim(),
//                    orderExpressModifiedRequest.getExpressNo().trim(),updateOrderFlag,orders.getShopId(),new Date(),orderExpressModifiedRequest.getExpressCompany().trim());
//        }
        if (StringUtils.isEmpty(yxBankerOrder.getExpressNo()) && !StringUtils.isEmpty(orderExpressModifiedRequest.getExpressNo())) {
            updateOrderFlag = 0;
            orderService.syncOrderExpress(yxBankerOrder.getChildOrderNo(),ExpressDicUtil.getValue(orderExpressModifiedRequest.getExpressCompany().trim()),
                    orderExpressModifiedRequest.getExpressNo().trim(),updateOrderFlag,orders.getShopId(),new Date(),orderExpressModifiedRequest.getExpressCompany().trim());
        }

        yxBankerOrder.setExpressNo(orderExpressModifiedRequest.getExpressNo().trim());
        yxBankerOrder.setExpressCode(ExpressDicUtil.getValue(orderExpressModifiedRequest.getExpressCompany().trim()));
        if (StringUtils.isEmpty(yxBankerOrder.getExpressCode())){
            yxBankerOrder.setExpressCode(orderExpressModifiedRequest.getExpressCompany().trim());
        }
        yxBankerOrder.setUpdateTime(new Date());
        yxBankerOrder.setIsExport((byte) 1);
        yxBankerOrder.setExportTime(new Date());
        yxBankerOrder.setDeliveryTime(new Date());
        yxBankerOrder.setOrderStatus(OrderTimerConstants.ORDER_STATUS_YES);
        yxBankerOrder.setIsSync((byte) 0);
        yxBankerOrder.setIsNewSync((byte) 0);
        yxBankerOrder.setOrderInfoStatus(2);
        yxBankerOrder.setImportTime(new Date());

        int i = bankerOrderMapper.updateByPrimaryKeySelective(yxBankerOrder);
        if (i > 0){
            //同步修改订单状态
            YxOrders yxOrders = orderService.queryByChildOrderNo(yxBankerOrder.getChildOrderNo());
            YxOrders nowOrders = new YxOrders();
            nowOrders.setId(yxOrders.getId());
            nowOrders.setOrderStatus(Integer.valueOf(OrderStatusEnums.DELIVERY.getStatus()));
            ordersMapper.updateByPrimaryKeySelective(nowOrders);
        }
        //如果存在异常单改为已处理
        YxOrderException yxOrderException = orderExceptionMapper.selectByPrimaryKey(yxBankerOrder.getId());
        if (null != yxOrderException) {
            YxOrderException newOrderException = new YxOrderException();
            newOrderException.setId(yxOrderException.getId());
            newOrderException.setStatus(new Byte("2"));
            newOrderException.setHandleTime(new Date());
            newOrderException.setHandlePerson(userInfo != null ? userInfo.getId().toString() : adminName);
            newOrderException.setExpressCode(ExpressDicUtil.getValue(orderExpressModifiedRequest.getExpressCompany().trim()));
            newOrderException.setExpressNo(orderExpressModifiedRequest.getExpressNo().trim());
            orderExceptionMapper.updateByPrimaryKeySelective(newOrderException);
            YxOrderExceptionNote yxOrderExceptionNote = new YxOrderExceptionNote();
            yxOrderExceptionNote.setCreateTime(new Date());
            yxOrderExceptionNote.setContent("【已处理】已更新快递单号-系统自动修改成已处理");
            yxOrderExceptionNote.setOrderExceptionId(yxOrderException.getId());
            yxOrderExceptionNote.setAdminName(userInfo != null ? userInfo.getId().toString() : adminName);
            orderExceptionNoteMapper.insertSelective(yxOrderExceptionNote);
        }
        //插入拆分快递信息
        List<ExpressRecordsRequest> expressRecordsList = orderExpressModifiedRequest.getExpressRecordsList();
        if (!CollectionUtils.isEmpty(expressRecordsList)) {
            String childOrderNo = yxBankerOrder.getChildOrderNo();
            expressRecordsMapper.updateInvalidFlag(childOrderNo);
            expressRecordsList.forEach(item ->{
                YxExpressRecords records = new YxExpressRecords();
                BeanUtils.copyProperties(item, records);
                records.setChildOrderNo(childOrderNo);
                records.setCreateTime(new Date());
                records.setInvalidFlag(0);
                expressRecordsMapper.insertSelective(records);
            });

        }
    }

    /**
     * 调用销售端接口更新订单快递单号
     * @param childOrderNo  子订单号
     * @param expressNo     快递单号
     * @param expressCompanyCode    快递公司编号
     * @param shopId    销售端编号
     */
    private void callbackSaleSystemUpdateOrderExpress(String childOrderNo, String expressNo, String expressCompanyCode, String shopId) {
        log.info("===callbackSaleSystemUpdateOrderExpress:{},{},{}", childOrderNo, expressNo, shopId);
        Example example2 = new Example(YxNotifyUrlInfo.class);
        example2.createCriteria().andEqualTo("type", 6).andEqualTo("shopId", shopId);
        List<YxNotifyUrlInfo> notifyUrlInfos = notifyUrlInfoMapper.selectByExample(example2);
        if (CollectionUtils.isEmpty(notifyUrlInfos)) {
            return;
        }
        YxNotifyUrlInfo notifyUrlInfo = notifyUrlInfos.get(0);
        Map<String, String> notifyParam = new HashMap<String, String>();
        notifyParam.put("type", "6");
        notifyParam.put("msg", "供应商修改订单:" + childOrderNo + "快递单号信息:" + expressNo);
        notifyParam.put("childOrderNo", String.valueOf(childOrderNo));
        notifyParam.put("expressNo", expressNo);
        notifyParam.put("expressCompanyCode", expressCompanyCode);
        String result = HttpClientUtil.doPost(notifyUrlInfo.getUrl(), notifyParam);
        log.info("===callbackSaleSystemUpdateOrderExpress result = {}", result);
    }

    public void updateOrderStatus(Integer id) {
        YxBankerOrder bankerOrder = new YxBankerOrder();
        bankerOrder.setId(id);
        bankerOrder.setOrderStatus((byte) 2);
        bankerOrderMapper.updateByPrimaryKeySelective(bankerOrder);
    }

    public void downloadExcel(Integer id, YxBanker userInfo, HttpServletResponse response) {
        //获取该文件的名称、后缀
        YxBankerExportRecord yxBankerExportRecord = bankerExportRecordMapper.selectById(id,1);
        if (userInfo.getLevel().equals(BankerConstants.LEVEL_PLATFORM)) {
            if (!userInfo.getId().equals(yxBankerExportRecord.getBankerId())) {
                throw new ApiException("暂无权限下载!");
            }
        }
        //文件在服务器的路径
        String serverPath = path + yxBankerExportRecord.getFileName();
        InputStream inputStream = null;
        OutputStream out = null;
        try {
            //根据文件在服务器的路径读取该文件转化为流
            File file = new File(serverPath);
            inputStream = new FileInputStream(file);
            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            response.setContentType("application/octet-stream;charset=ISO8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + yxBankerExportRecord.getFileName());
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");

            out = response.getOutputStream();
            int b = 0;
            while (b != -1) {
                b = inputStream.read(buffer);
                //写到输出流(out)中
                out.write(buffer, 0, b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                out.close();
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public List<NewBankerOrderResponse> findBankerOrderInfoByNo(String orderNo) {
        YxBanker userInfo = bankerService.getUserInfo();
        List<NewBankerOrderResponse> bankerOrderInfoByNo = bankerOrderMapper.findBankerOrderInfoByNo(orderNo);
        if (!CollectionUtils.isEmpty(bankerOrderInfoByNo) && !userInfo.getId().equals(bankerOrderInfoByNo.get(0).getBankerId())) {
            log.warn("===userInfo.id={}, bankerId={}", userInfo.getId(), bankerOrderInfoByNo.get(0).getBankerId());
            throw new ApiException("参数错误！");
        }

        bankerOrderInfoByNo.stream().map(item -> {
            item.setProcessStatus(2);

            // 快递编号和快递单号不为空,查询快递编号
            if (!StringUtils.isEmpty(item.getExpressNo()) && !StringUtils.isEmpty(item.getExpressCode())) {
                List<YxExpressDic> expressDicByExpressCode = expressDicService.queryExpressDicListByExpressValue(item.getExpressCode());
                item.setExpressCodeName(expressDicByExpressCode.get(0).getExpressKey());
            }

            item.setStatus(Integer.parseInt(OrderStatusEnums.WAIT_DELIVERY.getStatus()));

            // 判断是否发货 改变状态为 3
            if (!StringUtils.isEmpty(item.getExpressNo())) {
                item.setStatus(Integer.parseInt(OrderStatusEnums.FINISH.getStatus()));
            }
            if (item.getReceiveTime() != null) {
                item.setStatus(Integer.parseInt(OrderStatusEnums.NO_VALID.getStatus()));
            }
            if (item.getOrderInfoStatus().equals("2")) {
                item.setProcessStatus(3);
            }else if (item.getOrderInfoStatus().equals("3")) {
                item.setProcessStatus(5);
            }

            return item;
        }).collect(Collectors.toList());

        return bankerOrderInfoByNo;
    }

    /**
     * 供应链查看订单详情
     * @param orderNo
     * @return
     */
    public List<NewBankerOrderResponse> findSupplyOrderInfoById(String orderNo) {
        List<NewBankerOrderResponse> bankerOrderInfoByNo = bankerOrderMapper.findSupplyOrderInfoById(Integer.parseInt(orderNo));

        bankerOrderInfoByNo.stream().map(item -> {

//            YxProduct yxProduct = productMapper.selectByPrimaryKey(item.getProductId());
//            if (null != yxProduct){
//                item.setSupplyPrice(yxProduct.getSupplyPrice());
//            }

            // 快递编号和快递单号不为空,查询快递编号
            if (!StringUtils.isEmpty(item.getExpressNo()) && !StringUtils.isEmpty(item.getExpressCode())) {
                List<YxExpressDic> expressDicByExpressCode = expressDicService.queryExpressDicListByExpressValue(item.getExpressCode());
                item.setExpressCodeName(expressDicByExpressCode.get(0).getExpressKey());
            }

            item.setStatus(Integer.parseInt(OrderStatusEnums.WAIT_DELIVERY.getStatus()));

            // 判断是否发货 改变状态为 3
            if (!StringUtils.isEmpty(item.getExpressNo())) {
                item.setStatus(Integer.parseInt(OrderStatusEnums.FINISH.getStatus()));
            }
            if (item.getReceiveTime() != null) {
                item.setStatus(Integer.parseInt(OrderStatusEnums.NO_VALID.getStatus()));
            }
            item.setProcessStatus(2);
            if (item.getOrderInfoStatus().equals("2")) {
                item.setProcessStatus(3);
            }else if (item.getOrderInfoStatus().equals("3")) {
                item.setProcessStatus(5);
            }
            return item;
        }).collect(Collectors.toList());

        return bankerOrderInfoByNo;
    }

    public boolean confirmDelivery(NewBankerOrderResponse newBankerOrderResponse) {
        List<NewBankerOrderResponse> byNo = bankerOrderMapper.findBankerOrderInfoByChildOrderNo(newBankerOrderResponse.getChildOrderNo());
        if (!StringUtils.isEmpty(byNo.get(0).getExpressCode()) && !StringUtils.isEmpty(byNo.get(0).getExpressNo())) {
            throw new ApiException("您的订单已发货");
        }
        if (!byNo.get(0).getOrderInfoStatus().equals("6")
                && !byNo.get(0).getOrderInfoStatus().equals("4")
                && !byNo.get(0).getOrderInfoStatus().equals("3")) {
            if (null != newBankerOrderResponse.getExpressNo()) {
                newBankerOrderResponse.setExpressNo(newBankerOrderResponse.getExpressNo().trim());
            }
            bankerOrderMapper.confirmDelivery(newBankerOrderResponse);

            //同步供应链订单状态
            YxOrders yxOrders = orderService.queryByChildOrderNo(byNo.get(0).getChildOrderNo());
            YxOrders nowOrders = new YxOrders();
            nowOrders.setId(yxOrders.getId());
            nowOrders.setOrderStatus(Integer.valueOf(OrderStatusEnums.DELIVERY.getStatus()));
            ordersMapper.updateByPrimaryKeySelective(nowOrders);
            //快递公司
            List<YxExpressDic> yxExpressDics = expressDicService.queryExpressDicListByExpressValue(newBankerOrderResponse.getExpressCode());
            String expressName = "";
            if(yxExpressDics.size() > 0){
                expressName = yxExpressDics.get(0).getExpressKey();
            }
            //同步销售端的物流信息和订单状态
            orderService.syncOrderExpress(byNo.get(0).getChildOrderNo(),
                    newBankerOrderResponse.getExpressCode().trim(),newBankerOrderResponse.getExpressNo().trim(),0,yxOrders.getShopId(),new Date(),expressName);
        } else {
            return false;
        }
        return true;
    }

    public CommonResult querySupplyChainOrderInfo(List<String> childOrderNos) {
        if (CollectionUtils.isEmpty(childOrderNos)) {
            return CommonResult.success();
        }
        List<YxBankerOrder> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(childOrderNos)) {
            if (childOrderNos.size() >= 20) {
                int num = childOrderNos.size() / 20;
                int more = childOrderNos.size() % 20;
                if (more > 0) {
                    num = num + 1;
                }
                for (int i = 0; i < num - 1; i++) {
                    list.addAll(bankerOrderMapper.selectByChildOrderNoList(childOrderNos.subList(i * 20, i * 20 + 20)));
                }
                list.addAll(bankerOrderMapper.selectByChildOrderNoList(childOrderNos.subList((num - 1) * 20, childOrderNos.size())));
            } else {
                list = bankerOrderMapper.selectByChildOrderNoList(childOrderNos);
            }
        }

        List<YxExpressRecords> records = expressRecordsMapper.queryByChildOrderNoList(childOrderNos);
        List<OrderQueryResponse> result = new ArrayList<>();
        list.forEach(item -> {
            OrderQueryResponse response = new OrderQueryResponse();
            BeanUtils.copyProperties(item, response);
            response.setCostPrice(item.getProductPrice());
            String expressRecordStr = CollectionUtils.isEmpty(records)? "" :
                    records.stream().filter(record -> record.getChildOrderNo().equals(item.getChildOrderNo()))
                            .map(record -> ExpressDicUtil.getMapKey(record.getCompanyNo()) +":"+  record.getExpressEno()).collect(Collectors.joining("/"));
            response.setDeliveryRemark(expressRecordStr);
            result.add(response);
        });
        return CommonResult.success(result);
    }

    public YxBankerOrder selectByExpressCodeAndExpressNo(String expressCode, String expressNo) {
        Example example = new Example(YxBankerOrder.class);
        example.createCriteria().andEqualTo("expressCode", expressCode).andEqualTo("expressNo", expressNo);
        example.orderBy("id").desc();
        List<YxBankerOrder> bankerOrderList = bankerOrderMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(bankerOrderList)) {
            return null;
        }
        return bankerOrderList.get(0);
    }

    public List<YxBankerOrder> selectByChildOrderNos(List<String> childOrderNos) {
        Example example = new Example(YxBankerOrder.class);
        example.createCriteria().andIn("childOrderNo", childOrderNos);
        List<YxBankerOrder> bankerOrders = bankerOrderMapper.selectByExample(example);
        return bankerOrders;
    }
}
